package com.example.lotterysystem.service.activitystatus.impl;

import com.example.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.example.lotterysystem.common.exception.ServiceException;
import com.example.lotterysystem.service.ActivityService;
import com.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.example.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.example.lotterysystem.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class ActivityStatusManagerImpl implements ActivityStatusManager {


    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);
    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Autowired
    private ActivityService activityService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {

        if(CollectionUtils.isEmpty(operatorMap)) {
            logger.warn("operatorMap 为空！");
            return;
        }
        Map<String, AbstractActivityOperator> currMap  = new HashMap<>(operatorMap);
        Boolean update =  false;
        //1.先处理奖品 人员
        update = processConvertStatus(convertActivityStatusDTO,currMap,1);

        //2.处理活动

        update = processConvertStatus(convertActivityStatusDTO,currMap,2)||update;

        //缓存
        if(update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    @Override
    public void rollbackHandEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
            //扭转状态
            for(AbstractActivityOperator operator:operatorMap.values()) {
                operator.convert(convertActivityStatusDTO);
            }
            //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                      Map<String, AbstractActivityOperator> currMap,
                                      int sequence) {
        Boolean update = false;
        // 遍历currMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //看看operator是否转化
            if(operator.sequence() != sequence ||
             !operator.needConvert(convertActivityStatusDTO) ){
                continue;
            }
            //需要转化::
            if(!operator.convert(convertActivityStatusDTO)) {
                logger.error("{}转化失败！",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            //删除原有的operator
            iterator.remove();
            update = true;
        }
        //返回
        return update;
    }
}
